package com.zysc.processflow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zysc.processflow.common.util.StringUtils;
import com.zysc.processflow.entity.*;
import com.zysc.processflow.mapper.HandlerecordMapper;
import com.zysc.processflow.pojo.HandleRecordPO;
import com.zysc.processflow.pojo.RecordOpenParam;
import com.zysc.processflow.service.*;
import com.zysc.processflow.common.base.BaseService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 处置流程记录表 服务实现类
 * </p>
 *
 * @author 正元智慧城市_
 * @since 2022-11-18
 */
@Service
public class HandlerecordServiceImpl extends BaseService<HandlerecordMapper, Handlerecord> implements IHandlerecordService {

    @Autowired
    IHandleprocessnodeService handleprocessnodeService;
    @Autowired
    IHandlerecordcurrentnodeService handlerecordcurrentnodeService;
    @Autowired
    IHandleprocessService handleprocessService;
    @Autowired
    IProcessOperationService processOperationService;
    @Autowired
    IHandlerecorddetailService handlerecorddetailService;
    @Autowired
    IHandletaskService handletaskService;
    @Override
    public List<Handlerecord> GetHandlerecordListByPage(IPage<Handlerecord> page, String handlestatus, Long begintime, Long endtime, String id) {
        LambdaQueryWrapper<Handlerecord> qw = new LambdaQueryWrapper<>();
        qw.eq(!StringUtils.isNull(handlestatus),Handlerecord::getHandlestatus,handlestatus)
                .le(begintime!=null && begintime>0,Handlerecord::getStarttime,begintime)
                .ge(endtime!=null && endtime>0,Handlerecord::getStarttime,endtime)
                .eq(!StringUtils.isNull(id),Handlerecord::getId,id);
        if(page!=null){
            return this.baseMapper.selectPage(page,qw).getRecords();
        }else{
            return this.baseMapper.selectList(qw);
        }
    }

    @Override
    public List<HandleRecordPO> getNotFinishedAlarmRecord() {
        return this.baseMapper.getNotFinishedAlarmRecord();
    }

    @Override
    public List<HandleRecordPO> getNotFinishedAlarmRecordAfterTime(Long time) {
        return this.baseMapper.getNotFinishedAlarmRecordAfterTime(time);
    }
    //根据记录id,流程id,生成所有的该流程的活动节点
    @Override
    public List<Handlerecordcurrentnode> genAllInitProcessNodeList(String recordId, String processId) {
        Long tm = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
        LambdaQueryWrapper<Handleprocessnode> nodeQW = new LambdaQueryWrapper<>();
        nodeQW.eq(Handleprocessnode::getProcessid,processId);
        List<Handleprocessnode> list = handleprocessnodeService.list(nodeQW);
        //根据死节点,生成活节点
        List<Handlerecordcurrentnode> result = new ArrayList<>();
        list.forEach(node->{
            Handlerecordcurrentnode handlerecordcurrentnode = new Handlerecordcurrentnode();
            handlerecordcurrentnode.setProcessid(processId);
            handlerecordcurrentnode.setRecordid(recordId);
            handlerecordcurrentnode.setState("notstart");
            handlerecordcurrentnode.setCurrentnodeid(node.getId());
            handlerecordcurrentnode.setCurrentnodetype(node.getType());
            handlerecordcurrentnode.setCurrentorgid(node.getOrgid());
            handlerecordcurrentnode.setCurrentorgname(node.getOrgname());
            handlerecordcurrentnode.setCurrentdisposerid(node.getDisposerid());
            handlerecordcurrentnode.setCurrentdisposername(node.getDisposername());
            handlerecordcurrentnode.setCurrentroleid(node.getRoleid());
            handlerecordcurrentnode.setCurrentrolename(node.getRolename());
            if(StringUtils.equalsAndNotNull("1",node.getIsfirstnode())){//给开始节点加上活跃标记和活跃时间
                handlerecordcurrentnode.setState("active");
            }
            result.add(handlerecordcurrentnode);
        });
        return result;
    }

    @Override
    public HandleRecordPO startRecord(RecordOpenParam entity) {
        //1.获取流程信息
        String processid = entity.getProcessid();
        Handleprocess handleprocess = handleprocessService.getById(processid);
        //2.生成一条记录
        //2.1 根据找到的流程,取第一个节点-开始节点
        Handleprocessnode firstNode = processOperationService.getFirstNodeByProcess(handleprocess);
        //2.2 .组合流程和第一个审核节点的信息,生成一条记录信息
        HandleRecordPO handlerecord =  this.genHandlerecordByProcess(entity);
        //3.根据记录Id和process,生成该流程中全部节点的信息,存到活动节点表(记录该流程所有节点的状态等信息)里,此时所有的节点除开始节点都是notstart,开始节点是active
        List<Handlerecordcurrentnode> allProcessNodeList = handlerecord.getHandlerecordcurrentnodeList();
        //4.将记录信息保存
        Boolean b1 = this.save(handlerecord);
        //5.保存活动节点表
        Boolean b2 = handlerecordcurrentnodeService.saveBatch(allProcessNodeList);
        //6.生成一条"流程开始"记录
        Boolean b3 = handlerecorddetailService.addSystemRecordDetail(handlerecord.getId(),"流程开始", handlerecord.getStarttime());
        //7. 活动节点往后推一次 只有这里推一次 然后就是处置的时候推,消警的时候在推一次因未消警阻塞的节点一次
        Boolean b4 = processOperationService.pushNode(handlerecord,firstNode.getId());
        if(!b1 || !b2 ||!b3 ||!b4){
            throw new RuntimeException("操作失败,请联系管理员!");
        }
        //8.拿到此时的HandleRecordPO当作返回值
        HandleRecordPO result = this.getRecordFullInfoByRecordId(handlerecord.getId());
        return result;
    }

    @Override
    public Boolean checkRecordValid(RecordOpenParam entity) {
        String processid = entity.getProcessid();
        //1.校验是不是没有这个流程
        LambdaQueryWrapper<Handleprocess> processQW = new LambdaQueryWrapper<>();
        processQW.eq(Handleprocess::getId,processid);
        List<Handleprocess> handleprocessList = handleprocessService.list(processQW);
        if(handleprocessList.size() == 0){
            throw new RuntimeException("未找到流程");
        }
        //2.校验是不是这个业务系统对应的业务id,有没有未完成的业务
        LambdaQueryWrapper<Handlerecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
               .eq(Handlerecord::getYwxt,entity.getYwxt())
               .eq(Handlerecord::getYwxtid,entity.getYwxtid())
               .eq(Handlerecord::getHandlestatus,"0");//未审核完
        List<Handlerecord> handlerecordList = this.list(queryWrapper);
        if(handlerecordList.size()>0){
            throw new RuntimeException("该业务系统对应的业务id,有未完成的业务");
        }
        return true;
    }
    @Override
    public HandleRecordPO genHandlerecordByProcess(RecordOpenParam entity) {
        Long tm = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();

        HandleRecordPO handlerecord = new HandleRecordPO();
        handlerecord.setHandlestatus("0");
        handlerecord.setStarttime(tm);
        handlerecord.setProcessid(entity.getProcessid());
        handlerecord.setYwxt(entity.getYwxt());
        handlerecord.setYwxtid(entity.getYwxtid());
        handlerecord.setOrgid(entity.getOrgid());
        handlerecord.setOrgname(entity.getOrgname());
        handlerecord.setId(UUID.randomUUID().toString());

        List<Handlerecordcurrentnode> handlerecordcurrentnodes = this.genAllInitProcessNodeList(handlerecord.getId(), handlerecord.getProcessid());
        handlerecord.setHandlerecordcurrentnodeList(handlerecordcurrentnodes);
        return handlerecord;
    }

    @Override
    public HandleRecordPO getRecordFullInfoByRecordId(String id) {
        Handlerecord handlerecord = this.getById(id);
        if(handlerecord==null){
            throw new RuntimeException("未找到该记录");
        }
        List<Handlerecordcurrentnode> handlerecordcurrentnodeList = handlerecordcurrentnodeService.list(new LambdaQueryWrapper<Handlerecordcurrentnode>().eq(Handlerecordcurrentnode::getRecordid,id));
        List<Handletask> handletaskList = handletaskService.list(new LambdaQueryWrapper<Handletask>().eq(Handletask::getRecordid,id));
        List<Handlerecorddetail> handlerecorddetailList = handlerecorddetailService.list(new LambdaQueryWrapper<Handlerecorddetail>().eq(Handlerecorddetail::getRecordid,id).eq(Handlerecorddetail::getType,"处置任务"));
        HandleRecordPO result = new HandleRecordPO();
        BeanUtils.copyProperties(handlerecord,result);
        result.setHandlerecordcurrentnodeList(handlerecordcurrentnodeList);
        result.setHandletaskList(handletaskList);
        result.setHandlerecorddetailList(handlerecorddetailList);
        return result;
    }

    @Override
    public Boolean deleteRecordById(String id) {
        boolean b1 = true;
        boolean b2 = true;
        boolean b3 = true;
        boolean b4 = true;
        HandleRecordPO fullInfoByRecordId = this.getRecordFullInfoByRecordId(id);
        List<Handletask> handletaskList = fullInfoByRecordId.getHandletaskList();
        List<Handlerecorddetail> handlerecorddetailList = fullInfoByRecordId.getHandlerecorddetailList();
        List<Handlerecordcurrentnode> handlerecordcurrentnodeList = fullInfoByRecordId.getHandlerecordcurrentnodeList();
        if(handletaskList.size()>0){
            b1 = handletaskService.removeBatchByIds(handletaskList);
        }
        if(handlerecorddetailList.size()>0){
            b2 = handlerecorddetailService.removeBatchByIds(handlerecorddetailList);
        }
        if(handlerecordcurrentnodeList.size()>0){
            b3 = handlerecordcurrentnodeService.removeBatchByIds(handlerecordcurrentnodeList);
        }
        return b1&&b2&&b3 && this.removeById(id);
    }
}
